// ==UserScript==
// @name 校友邦实习一键评价 XiaoYouBang Auto Review
// @namespace https://github.com/lcandy2/XiaoYouBang-Auto-Review
// @version 1.0
// @author lcandy2
// @description 一键评价,自动填写评价内容
// @license MIT
// @icon https://www.xybsyw.com/favicon.ico
// @match *://www.xybsyw.com/personal/*
// @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js
// @run-at document-start
// ==/UserScript==
(function ($) {
'use strict';
const config = {
autoSubmit: false,
// 是否自动提交
day: 1,
// 天数类评价
rate: 5,
// 评分类评价 1-5
review: "好",
// 评价内容
suggestions: "无",
// 建议内容
addCourse: "无",
// 增加课程
radio: 0,
// 单选选择索引,从 0 开始
reviewHref: "myEvaluationDetail"
// 评价页面的 href,无特殊情况不需要修改
};
const fillInputs = (inputElement, data) => {
new Event("input", {
bubbles: true,
cancelable: true
});
inputElement.focus();
data.split("").forEach((char) => {
let keydownEvent = new KeyboardEvent("keydown", { key: char, bubbles: true });
let keyupEvent = new KeyboardEvent("keyup", { key: char, bubbles: true });
let inputEvent = new Event("input", { bubbles: true });
inputElement.dispatchEvent(keydownEvent);
inputElement.value += char;
inputElement.dispatchEvent(inputEvent);
inputElement.dispatchEvent(keyupEvent);
});
inputElement.blur();
};
const Review = () => {
const $allInput = $("input.el-input__inner");
const $dayInput = $allInput.filter((index, element) => {
return $(element).attr("max") !== void 0 && $(element).attr("min") !== void 0;
});
const $otherInput = $allInput.not($dayInput);
const $courseInput = $otherInput.filter((index, element) => {
return $(element).attr("placeholder").includes("课程");
});
const $allRate = $("div.el-rate");
const $allTextarea = $("textarea.el-textarea__inner");
const $suggestTextarea = $allTextarea.filter((index, element) => {
return $(element).attr("placeholder").includes("建议");
});
const $otherTextarea = $allTextarea.filter((index, element) => {
return !$(element).attr("placeholder").includes("建议");
});
const $allRadio = $("div.radioItem");
$dayInput.each((index, element) => {
fillInputs(element, config.day.toString());
});
$courseInput.each((index, element) => {
fillInputs(element, config.addCourse);
});
$allRate.each((index, element) => {
$(element).children().eq(config.rate - 1).trigger("click");
});
$otherTextarea.each((index, element) => {
fillInputs(element, config.review);
});
$suggestTextarea.each((index, element) => {
fillInputs(element, config.suggestions);
});
$allRadio.each((index, element) => {
$(element).children().eq(config.radio).trigger("click");
});
console.log("Review success!");
};
const addReviewButton = (listener) => {
if ($("button.--lcandy2-xyb-auto-review").length)
return;
const $topContent = $("div.contentItem div.topContent");
const $topContent_item = $topContent.children().eq(1);
const $reviewButton = $(``);
$reviewButton.on("click", () => {
config.autoSubmit = false;
listener();
});
const $reviewAndSubmitButton = $(``);
$reviewAndSubmitButton.on("click", () => {
config.autoSubmit = true;
listener();
});
$topContent_item.append($reviewButton);
$topContent_item.append($reviewAndSubmitButton);
console.log("Add Review Button", $reviewButton);
};
const watchUrlChange = (onChange) => {
const originalPushState = history.pushState;
history.pushState = function(state, title, url) {
originalPushState.apply(this, arguments);
onChange(url);
};
const originalReplaceState = history.replaceState;
history.replaceState = function(state, title, url) {
originalReplaceState.apply(this, arguments);
onChange(url);
};
window.addEventListener("popstate", () => {
onChange(document.location.href);
});
};
const executeReview = async () => {
Review();
const $submitButton = $("div.bottomDiv button.submitBtn");
$submitButton.val("评价完成,点击提交评价");
if (config.autoSubmit) {
$submitButton.trigger("click");
alert("评价完成,已自动提交。");
}
};
const main = () => {
const href = window.location.href;
if (!href.includes(config.reviewHref))
return;
addReviewButton(executeReview);
};
$(async () => {
main();
watchUrlChange((newUrl) => {
console.log("URL 变化了:", newUrl);
const observer = new MutationObserver((mutations) => {
for (let mutation of mutations) {
if (mutation.addedNodes.length) {
const $topContent = $("div.contentItem div.topContent");
if ($topContent.length) {
observer.disconnect();
main();
break;
}
}
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
});
})(jQuery);